package bsf.system.typeconvert;

import bsf.base.BsfException;
import bsf.util.ConvertUtil;

import java.util.HashMap;

/**
 * Created by chejiangyi on 2016/3/19.
 * 自动类型转换器提供类
 */
public class AutoTypeConvertProvider {

    public static HashMap<ConvertInfo,ITypeConvert> Converters = new HashMap();
    private static Object lockRegisterConverter=new Object();

    static {
        CommonTypeConvertRegister.register();
    }

    public static void registerConverter(Class<?>fromtype,Class<?>totype,ITypeConvert converter)
    {
        ConvertInfo info = new ConvertInfo();info.fromType = fromtype;info.toType = totype;
        if(!Converters.containsKey(info)) {
            synchronized (lockRegisterConverter) {
                if(!Converters.containsKey(info)) {
                    Converters.put(info,converter);
                }
            }
        }
    }



    public <T> T convert(Object obj, Class<T> totype) {
        if(obj.getClass() == totype)
        {
            return (T)obj;
        }
        ConvertInfo info = new ConvertInfo();info.fromType = obj.getClass();info.toType = totype;
        if(Converters.containsKey(info)) {
           ITypeConvert converter = Converters.get(info);
            return (T)converter.convert(obj);
        }

        return (T)defaultTypeConveret(obj,totype);

    }


        private Object defaultTypeConveret(Object o,Class<?> totype)
        {
            //fromtype ->String->totype
            try {
                if(o == null)
                    return totype.newInstance();
                String stringValue = ConvertUtil.nullToStr(o);
                if(totype == String.class)
                {
                    return stringValue;
                }
                else
                {
                    ConvertInfo info = new ConvertInfo();info.fromType = String.class;info.toType = totype;
                    if(Converters.containsKey(info)) {
                        ITypeConvert converter = Converters.get(info);
                        return converter.convert(stringValue);
                    }
                }
            }
            catch (Exception exp)
            {

            }
            //try to cast
            try
            {

                totype.cast(o);
                return o;
            }
            catch (Exception exp)
            {
                // AutoMapDebugLogHelper.errorln("[警告]typeConveret:"+exp.getMessage());
            }

            throw new BsfException("defaultTypeConveret method error:can not to convert to type ["+ totype.getName()+"]");

        }
}
